require 'socket'
require 'model_class'
require 'xml_parser'
require 'time'
require 'pause'
require 'timeout'

class MusicController < ApplicationController
	layout "standard-layout"
	def index
		list
		render :action => 'list'
	end

	def pause
		session["pause_info"].button_clicked()
		render :partial => "playing_controls"
	end

	def random
		clt = session['client']
		if(clt.nil?)
			render_text ""
			return
		end
		name = clt.name
		sock = TCPSocket.new('localhost', 12346)
		sock.puts("<play client=\"#{name}\" random=\"random\"/>")
		node = nil
		recv = ""
		while node.nil?
			begin
				recv += sock.recvfrom(1024).join()
				tmp = recv
				parser = XmlParser.new(tmp)
				node = parser.parse()
			rescue
				node = nil
			end
		end
		sock.close()

		# locate file...
		file = node["file"]
		@model = get_model()
		hash = @model.find_title_from_file(session["client"], file)
		session['title'] = hash["title"]
		session['album'] = hash["album"]
		session['artist'] = hash["artist"]
		session['client'] = hash["client"]

		session['playing'] = true
		session['play_title'] = session['title']
		session['play_client'] = session['client']
		session['play_progress'] = 0
		session['play_start'] = Time.new
		session['pause_info'] = Pause.new(session['client'], 
						   'localhost', 12346)
		render :partial => "list2"
	end

	def play
		title = session["title"]
		client = session["client"]
		if(title.nil? || client.nil?)
			return
		end

		begin
			# first of all, check if new client 
			if(!session['client'].nil? and
			   session['client'] != session['play_client'] and 
			   session['playing'] == true and
			   !session['pause_info'].is_paused)
				clt = session['play_client'].name
				sck = TCPSocket.new('localhost', 12346)
				sck.puts("<pause client=\"#{clt}\"/>")
				sck.close()
			end

			t = TCPSocket.new('localhost', 12346)
			t.puts("<play client=\"#{client.name}\" 
				file=\"#{title.file}\"/>\n")
			session['playing'] = true
			session['play_title'] = session['title']
			session['play_client'] = session['client']
			session['play_progress'] = 0
			session['play_start'] = Time.new
			session['pause_info'] = Pause.new(session['client'], 
							   'localhost', 12346)
			t.close()
		rescue => err
			logger.info err.to_s
			return
		end
		render :partial => "playing_controls"
	end

	def check_play
		if(session['playing'].nil? || !session['playing'] || 
		   session['play_title'].nil?)
			render :partial => "playing_controls"
			return
		end
		session['play_progress'] = (Time.new - 
			session['play_start'])
		session['play_progress'] -= session['pause_info'].pause_time
		session['play_progress'] = session['play_progress'].to_i
		if(session['play_progress'] >= 
		   session['play_title'].duration.to_i)
		   	sock = TCPSocket.new('localhost', 12346)
			clt = session['play_client'].name
			sock.puts("<pause client=\"#{clt}\"/>")
			sock.close()
			session['playing'] = false
		end
		render :partial => "playing_controls"
	end

	def list
		@model = get_model()
		logger.info @model
		if(@model.nil? or 
		   (!session['client'].nil? and 
		    @model.find_client(session['client'].name).nil?))
			session['client'] = nil
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
		end
		tmp = ['client_id', 'artist_id', 'album_id', 'title_id']
		for t in tmp
			if !params[t].nil?
				case t
					when 'client_id'
						update_client(params[t])
					when 'artist_id'
						update_artist(params[t])
					when 'album_id'
						update_album(params[t])
					when 'title_id'
						update_title(params[t])
					else raise 'impossible error'
				end
				render :partial => 'list'
				return
			end
		end
		logger.info "finished controller"
	end
	
	def update_client(clt)
		if(session['client'].nil?)
			session['client'] = @model.find_client(clt)
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
		elsif(session['client'].name == clt)
			return
		else
			session['client'] = @model.find_client(clt)
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
		end
	end

	def update_artist(art)
		if(session['client'].nil?)
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
			return
		end
		if(session['artist'].nil?)
			session['artist'] = session['client'].artists[art]
			session['album'] = nil
			session['title'] = nil
		elsif(session['artist'].name == art)
			return
		else
			session['artist'] = session['client'].artists[art]
			session['album'] = nil
			session['title'] = nil
		end
	end

	def update_album(alb)
		if(session['artist'].nil? or session['client'].nil?)
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
			return
		end
		if(session['album'].nil?)
			session['album'] = session['artist'].albums[alb]
			session['title'] = nil
		elsif(session['album'].name == alb)
			return
		else
			session['album'] = session['artist'].albums[alb]
			session['title'] = nil
		end
	end

	def update_title(t)
		if(session['album'].nil? or session['artist'].nil? or
		   session['client'].nil?)
			session['artist'] = nil
			session['album'] = nil
			session['title'] = nil
			return
		end
		if(session['title'].nil?)
			session['title'] = session['album'].titles[t]
		elsif(session['title'].name == t)
			return
		else
			session['title'] = session['album'].titles[t]
		end
	end

	def get_model()
		logger.info "get_model()"
		t = nil
		begin
			t = TCPSocket.new('localhost', 12346)
			t.puts("<list/>\n")
		rescue
			return
		end

		node = nil
		answer = "<model>"
		while node.nil?
			begin
				timeout(11) do
					@buff = t.recvfrom(1024).join()
				end
				answer += @buff.gsub(/&/, '&amp;')
				tmp = answer + "</model>"
				parser = XmlParser.new(tmp)
				node = parser.parse()
			rescue TimeoutError
				return nil
			rescue => err
				logger.info err.to_s
				node = nil
			end
		end
		t.close()

		@model = ModelClass.instance()
		@model.clear
		@model.parse(node)
		return @model
	end
end

